# 导入必要的模块和类
from fastapi import APIRouter, Request, HTTPException  # 导入FastAPI相关组件，用于创建API路由和处理HTTP请求
from dotenv import load_dotenv  # 导入用于加载环境变量的工具

# 以下是被注释掉的导入，表示之前使用过但现在不再使用的服务
# from app.services.claude_service import ClaudeService  # Claude AI服务，现已不使用
# from app.core.limiter import limiter  # 请求限制器，用于限制API调用频率，现已注释
from anthropic._exceptions import RateLimitError  # 导入Anthropic API的速率限制异常
from app.prompts import SYSTEM_MODIFY_PROMPT  # 导入用于修改图表的系统提示词
from pydantic import BaseModel  # 导入用于数据验证和模型定义的Pydantic基类
from app.services.o1_mini_openai_service import OpenAIO1Service  # 导入OpenAI o1-mini模型服务


# 加载环境变量，确保能够访问到.env文件中的配置
load_dotenv()

print("========== 初始化 OpenAI 修改路由 ==========")

# 创建API路由器，设置前缀为"/openai/modify"，标签为"openai"
# 注意：虽然标签为"Claude"，但实际上现在使用的是OpenAI的服务
router = APIRouter(prefix="/openai/modify", tags=["openai"])

# 初始化服务
# 以下是被注释掉的服务初始化，表示不再使用Claude服务
# claude_service = ClaudeService()
# 初始化OpenAI o1-mini服务，用于处理图表修改请求
o1_service = OpenAIO1Service()
print("已初始化 OpenAIO1Service 服务")


# 定义请求体模型，用于验证和解析传入的JSON数据
class ModifyRequest(BaseModel):
    instructions: str  # 用户提供的修改指令
    current_diagram: str  # 当前的图表代码
    repo: str  # 仓库名称
    username: str  # 用户名
    explanation: str  # 图表的解释说明
    model: str = "gpt-3.5-turbo"  # 默认使用gpt-3.5-turbo模型
    api_key: str | None = None  # 可选的API密钥


# 定义POST请求处理函数
@router.post("")
# 以下是被注释掉的请求限制器，限制每分钟2次，每天10次调用
# @limiter.limit("2/minute;10/day")
async def modify(request: Request, body: ModifyRequest):
    print(f"[OpenAI] 修改请求: 用户名={body.username}, 仓库={body.repo}, 指令长度={len(body.instructions)}, 模型={body.model}")
    try:
        # 检查指令和图表是否存在
        if not body.instructions or not body.current_diagram:
            print("[OpenAI] 错误: 缺少指令或当前图表")
            return {"error": "Instructions and/or current diagram are required"}
        # 检查指令和图表长度是否超过限制
        elif (
            len(body.instructions) > 1000 or len(body.current_diagram) > 100000
        ):  # 设置长度限制是为了安全考虑
            print("[OpenAI] 错误: 指令长度超过限制")
            return {"error": "Instructions exceed maximum length of 1000 characters"}

        # 检查是否为示例仓库，示例仓库不允许修改
        if body.repo in [
            "fastapi",
            "streamlit",
            "flask",
            "api-analytics",
            "monkeytype",
        ]:
            print("[OpenAI] 错误: 示例仓库不允许修改")
            return {"error": "Example repos cannot be modified"}

        # 以下是被注释掉的Claude API调用代码，表示不再使用Claude服务
        # modified_mermaid_code = claude_service.call_claude_api(
        #     system_prompt=SYSTEM_MODIFY_PROMPT,
        #     data={
        #         "instructions": body.instructions,
        #         "explanation": body.explanation,
        #         "diagram": body.current_diagram,
        #     },
        # )

        print("[OpenAI] 开始调用o1-mini API修改图表")
        
        # 调用OpenAI o1-mini API修改图表
        # 传入系统提示词和包含指令、解释和图表的数据
        modified_mermaid_code = o1_service.call_o1_api(
            system_prompt=SYSTEM_MODIFY_PROMPT,  # 使用专门为修改图表设计的系统提示词
            data={  # 传入需要处理的数据
                "instructions": body.instructions,  # 用户的修改指令
                "explanation": body.explanation,  # 图表的解释说明
                "diagram": body.current_diagram,  # 当前的图表代码
            },
            api_key=body.api_key,  # 传入可选的API密钥
            model=body.model,  # 传入模型参数
        )
        
        print(f"[OpenAI] API调用完成: 修改后代码长度={len(modified_mermaid_code)}")

        # 检查返回结果是否包含"BAD_INSTRUCTIONS"，这表示用户提供的指令无效或不明确
        if "BAD_INSTRUCTIONS" in modified_mermaid_code:
            print("[OpenAI] 错误: 无效或不明确的指令")
            return {"error": "Invalid or unclear instructions provided"}

        # 返回修改后的图表代码
        print("[OpenAI] 修改成功, 返回修改后的图表")
        return {"diagram": modified_mermaid_code}
    # 捕获API速率限制异常
    except RateLimitError as e:
        # 抛出HTTP 429异常，表示请求过多
        print(f"[OpenAI] 速率限制错误: {str(e)}")
        raise HTTPException(
            status_code=429,
            detail="Service is currently experiencing high demand. Please try again in a few minutes.",
        )
    # 捕获所有其他异常
    except Exception as e:
        # 返回错误信息
        print(f"[OpenAI] 处理过程中出错: {str(e)}")
        return {"error": str(e)}
